package ai.people.platform.archives.ws.server;

import ai.people.core.security.support.RequestHolderUtil;
import ai.people.netmon.framework.exception.type.BusinessException;
import ai.people.platform.archives.ws.config.WebSocketConfig;
import ai.people.platform.archives.ws.context.WsExecutorContext;
import ai.people.platform.archives.ws.context.WsSessionContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;

/**
 * websocket服务
 *
 * @author LiGuanNan
 * @date 2022/7/6 18:23
 */
@Slf4j
@Component
@RequiredArgsConstructor
@ServerEndpoint(value = "/ws-server/{tag}", configurator = WebSocketConfig.class)
public class WebSocketServer {

    /**
     * 连接成功
     *
     * @param session
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("tag") String tag) {
        SecurityContextHolder.getContext().setAuthentication((Authentication) session.getUserPrincipal());
        log.info("websocket连接建立成功，tag：{}，userId:{}", tag, RequestHolderUtil.getUserId());
        WsExecutorContext.getWebSocketExecutorByTag(tag).onOpen(session);
        WsSessionContext.ALL_SESSIONS.add(session);
    }

    /**
     * 连接关闭
     *
     * @param session
     */
    @OnClose
    public void onClose(Session session, @PathParam("tag") String tag) {
        SecurityContextHolder.getContext().setAuthentication((Authentication) session.getUserPrincipal());
        log.info("websocket连接关闭，tag：{}，userId:{}", tag, RequestHolderUtil.getUserId());
        WsExecutorContext.getWebSocketExecutorByTag(tag).onClose(session);
        WsSessionContext.ALL_SESSIONS.remove(session);
    }

    /**
     * 接收到消息
     *
     * @param text
     */
    @OnMessage
    public void onMsg(String text, Session session, @PathParam("tag") String tag) {
        SecurityContextHolder.getContext().setAuthentication((Authentication) session.getUserPrincipal());
        log.info("websocket连接接收消息，tag：{}, userId:{}, text:{}", tag, RequestHolderUtil.getUserId(), text);
        try {
            WsExecutorContext.getWebSocketExecutorByTag(tag).onMsg(text, session);
        }catch (Exception e){
            e.printStackTrace();
            try {
                if(e instanceof BusinessException){
                    session.getBasicRemote().sendText(e.getMessage());
                }else {
                    session.getBasicRemote().sendText("系统异常，请重新刷新页面并重试");
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

}
